import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, IsNull, Not, Repository } from 'typeorm';
import { WithdrawingEnum } from '../wxUser/wxUser.enum';
import { Profit } from './profit.entity';
import { EnumProfitRefundReasonText, EnumProfitRefundReasonType, profitEnum, profitTypeEnum } from './profit.enum';
import { Questions } from '../questions/questions.entity';
import DataBase from 'src/config/database';
import { AnswerReportErrors } from '../answerReportErrors/answerReportErrors.entity';
import { ReportSourceEnum } from '../answerReportErrors/answerReportErrors.enum';
import { RewardSuccess } from '../rewardSuccess/rewardSuccess.entity';
import { Reward } from '../reward/reward.entity';
import { payStatusEnum } from '../reward/reward.enum';
import { ProfitRefund } from '../profitRefund/profitRefund.entity';
import { EnumProfitRefundType, profitRefundStatusEnum } from '../profitRefund/profitRefund.enum';
import { WXAPI } from 'src/common/wx_api';
import { Notices } from '../notices/notices.entity';
import { NoticeCheckEnum, NoticeTypeEnum } from '../notices/notices.enum';
import { Answer } from '../answer/answer.entity';
import { WsStartGateway } from '../ws/ws.gateway';
import { ProfitUnLockHome } from '../profitUnLockHome/profitUnLockHome.entity';
import { EnumProfitUnLockHome_Status } from '../profitUnLockHome/profitUnLockHome.enum';
import { RejectReason } from '../rejectReason/rejectReason.entity';
import { getQueryVideoField, videoFields } from 'src/common/sql/video';
import utils from 'src/common/utils';
import { RedisCacheService } from '../redisCache/redisCache.service';
let WXAPIOBJ = new WXAPI()

@Injectable()
export class ProfitService {
  constructor(
    @InjectRepository(Profit)
    private repository: Repository<Profit>,
    @InjectRepository(Questions)
    private questionsRepository: Repository<Questions>,
    @InjectRepository(AnswerReportErrors)
    private answerReportErrorsRepository: Repository<AnswerReportErrors>,
    @InjectRepository(RewardSuccess)
    private rewardSuccessRepository: Repository<RewardSuccess>,
    @InjectRepository(Reward)
    private rewardRepository: Repository<Reward>,
    @InjectRepository(ProfitRefund)
    private profitRefundRepository: Repository<ProfitRefund>,
    @InjectRepository(Answer)
    private answerRepository: Repository<Answer>,
    @InjectRepository(Notices)
    private noticesRepository: Repository<Notices>,
    @InjectRepository(ProfitUnLockHome)
    private profitUnLockHomeRepository: Repository<ProfitUnLockHome>,
    private readonly wsStartGateway: WsStartGateway,
    @InjectRepository(RejectReason)
    private rejectReasonRepository: Repository<RejectReason>,
    private readonly redisCacheService: RedisCacheService,

  ) { }


  /**
   * 查询用户可提现的金额
   * @param wx_user 
   * @returns 
   */
  async findWithdrawal(wx_user: string) {
    let dataList = await this.repository.query(`
      select sum(totalPrice) as totalPrice from (
        select sum(unit_price) as totalPrice from profit 
        where status = 1 and author_wx_user = ?
        union all
        select sum(unit_price) as totalPrice from profit_unlock_home 
        inner join video on video.id = profit_unlock_home.video_id
        where profit_unlock_home.status = 1 and video.wx_user = ? 
      ) a
    `, [wx_user, wx_user])
    //提现记录
    let tx = await this.repository.query(`
      select sum(use_amount) as totalPrice from wallet_flow where status = 1 and wx_user = ?
    `, [wx_user])

    //提问的人返还悬赏金

    //追加悬赏的人返还悬赏金


    //追加选上的人获得普通收益


    //查询用户是否能提现
    let isOutAccount = await this.repository.query(`
      select withdrawing from wx_user where openid = ?
    `, [wx_user])
    let totalPrice = 0, withdrawing = false
    if (isOutAccount.length > 0) {
      withdrawing = isOutAccount[0].withdrawing == WithdrawingEnum.withdrawing ? true : false
    }
    if (dataList.length > 0) {
      totalPrice = dataList[0].totalPrice
    }

    if (tx.length > 0) {
      totalPrice = totalPrice - tx[0].totalPrice
    }

    // if(rewardPrice.length > 0){
    //   totalPrice = totalPrice + Number(rewardPrice[0].totalPrice)
    // }

    return {
      totalPrice: totalPrice,
      withdrawing: withdrawing
    }
  }

  /**
   * 查询所有用户的收入
   */
  async findAll_By_User(skip: number, take: number, wx_user: string): Promise<{ data: [], totalPrice: Number, total: Number }> {
    let dataList = await this.repository.query(`
      select create_time, sum(totalPrice) totalPrice from (
        select substring(a.create_time, 1, 10) create_time,sum(a.unit_price) totalPrice from profit a
        where a.status = 1 and a.author_wx_user = ?
        group by substring(a.create_time, 1, 10)
        union all
        select substring(a.create_time, 1, 10) create_time,sum(a.unit_price) totalPrice from profit_unlock_home a
        inner join video on video.id = a.video_id
        where a.status = 1 and video.wx_user = ?
        group by substring(a.create_time, 1, 10)
      ) a
      group by a.create_time
      order by a.create_time desc
      limit ?,?
    `, [wx_user, wx_user, skip, take])

    let total = await this.repository.query(`
      select count(1) as total from (
        select 1 from (
          select substring(a.create_time, 1, 10) create_time from profit a
          where a.status = 1 and a.author_wx_user = ?
          group by substring(a.create_time, 1, 10)
          union all
          select substring(a.create_time, 1, 10) create_time from profit_unlock_home a
          inner join video on video.id = a.video_id
          where a.status = 1 and video.wx_user = ?
          group by substring(a.create_time, 1, 10)
        ) a
        group by a.create_time
      )a
    `, [wx_user, wx_user])

    let totalPrice = await this.repository.query(`
      select sum(totalPrice) totalPrice from (
        select sum(a.unit_price) totalPrice from profit a
        where a.status = 1 and a.author_wx_user = ?
        union all
        select sum(a.unit_price) totalPrice from profit_unlock_home a
        inner join video on video.id = a.video_id
        where a.status = 1 and video.wx_user = ?
      ) a
    `, [wx_user, wx_user])
    return { data: dataList, totalPrice: Number(totalPrice[0].totalPrice || 0), total: Number(total[0].total || 0) }

  }
  /**
   * 查询某个作品的所有收入记录
   * @param skip
   * @param take
   * @param wallet_flow_id
   * @returns
   */
  async findAll_By_Video(skip: number, take: number, video_id: number, wx_user: string): Promise<{ data: [], totalPrice: 0, total: Number }> {
    let dataList = await this.repository.query(`
      select a.create_time, sum(a.totalPrice) as totalPrice from (
        select substring(a.create_time, 1, 10) create_time,sum(a.unit_price) totalPrice from profit a
        inner join answer b on b.id = a.answer_id
        where b.video_id = ? and a.status = 1 and a.unit_price > 0 and a.author_wx_user = ?
        group by substring(a.create_time, 1, 10)
        union all
        select substring(a.create_time, 1, 10) create_time,sum(a.unit_price) totalPrice from profit_unlock_home a
        inner join video on video.id = a.video_id
        where a.video_id = ? and a.status = 1 and a.unit_price > 0 and video.wx_user = ?
        group by substring(a.create_time, 1, 10)
      ) a
      group by a.create_time
      order by a.create_time desc
      limit ?,?
    `, [video_id, wx_user, video_id, wx_user, skip, take])

    let total = await this.repository.query(`
      select count(1) as total from (
        select a.create_time from (
          select substring(a.create_time, 1, 10) create_time from profit a
          inner join answer b on b.id = a.answer_id
          where b.video_id = ? and a.status = 1 and a.unit_price > 0 and a.author_wx_user = ?
          group by substring(a.create_time, 1, 10)
          union all
          select substring(a.create_time, 1, 10) create_time from profit_unlock_home a
          inner join video on video.id = a.video_id
          where a.video_id = ? and a.status = 1 and a.unit_price > 0 and video.wx_user = ?
          group by substring(a.create_time, 1, 10)
        ) a
        group by a.create_time
      ) a
    `, [video_id, wx_user, video_id, wx_user])

    let totalPrice = await this.repository.query(`
      select sum(a.totalPrice) as totalPrice from (
        select sum(a.unit_price) totalPrice from profit a
        inner join answer b on b.id = a.answer_id
        where b.video_id = ? and a.status = 1 and a.unit_price > 0 and a.author_wx_user = ?
        union all
        select sum(a.unit_price) totalPrice from profit_unlock_home a
        inner join video on video.id = a.video_id
        where a.video_id = ? and a.status = 1 and a.unit_price > 0 and video.wx_user = ?
      ) a
    `, [video_id, wx_user, video_id, wx_user])
    return { data: dataList, totalPrice: totalPrice[0].totalPrice, total: Number(total[0].total) }
  }

  /**
   * 查询提现详情
   * @param skip
   * @param take
   * @param wallet_id
   * @returns
   */
  findAll_By_Wallet(skip: number, take: number, wallet_flow_id: number): Promise<Profit[]> {
    return this.repository.query(`
      select a.*,e.video_key,e.id from profit a
      inner join wallet_flow b on b.id = a.wallflow_id
      inner join answer c on c.id = a.answer_id
      inner join video e on e.id = c.video_id
      where b.id = ?
      order by a.update_time,a.create_time desc
      limit ?,?
    `, [wallet_flow_id, skip, take])
  }

  /**
   * 查询用户的收益（原创/非原创）
   * @param skip
   * @param take
   * @param wx_user
   * @param original
   * @returns
   */
  async findAll_My_By_Original(skip: number, take: number, wx_user: string, original: number): Promise<{ data: Profit[], total: number }> {
    let dataList: any = [], total = 0
    let overseas = 3
    let findOverseas = await this.repository.query(`
      select user_setting.value from user_setting where user_setting.key = 'overseas' and user_setting.wx_user = ?
    `, [wx_user])
    if (findOverseas.length > 0 && findOverseas[0].value == 1) {
      overseas = 1
    }
    if (original == 1) {
      dataList = await this.repository.query(`
        select 
          video.id,
          video.id_card,
          video.check_time,
          video.overseas,
          video.ic_group,
          video.original,
          video.profit_type,
        (
          select sum(unit_price) 
          from profit
          where profit.answer_id = answer.id
        ) as profit_unit_price,
        (
          select sum(unit_price) 
          from profit_unlock_home
          where profit_unlock_home.video_id = video.id
        ) as unlock_home_profit_unit_price, 
        (
          select count(1) from video
          where video.wx_user = ? and (video.overseas = ? ${overseas == 3 ? ' or video.overseas = 0' : ''}) and video.delete_tag = 0 and video.id = answer.video_id
        ) as video_unable
        from answer
        inner join video on video.id = answer.video_id
        where (answer.type = 2 or answer.type = 3 or answer.type = 4) and answer.check = 1 and answer.wx_user = ? and video.check = 1
        order by video.id desc
        limit ?,?
      `, [wx_user, overseas, wx_user, skip, take])

      dataList.map(e => {
        e.profit_unit_price = Number(e.profit_unit_price || 0)
        e.unlock_home_profit_unit_price = Number(e.unlock_home_profit_unit_price || 0)
        e.profit_unit_price += e.unlock_home_profit_unit_price
        delete e.unlock_home_profit_unit_price
      })
      total = await this.repository.query(`
        select count(1) as total
        from answer
        inner join video on video.id = answer.video_id
        where (answer.type = 2 or answer.type = 3 or answer.type = 4) and answer.check = 1 and answer.wx_user = ? and video.check = 1
      `, [wx_user])
      dataList.map(e => {
        if (e.overseas == 3 && !e.ic_group && e.original == 1 && e.profit_type == 1) {
          delete e.id_card
        }
        delete e.overseas
        delete e.ic_group
        delete e.original
        delete e.profit_type
      })
    } else {
      dataList = await this.repository.query(`
        select 
          c.id,
          a.id_card,
          a.check_time,
          (
            select sum(unit_price) from profit
            where profit.answer_id = a.id
          ) as profit_unit_price, case when a.delete_tag = 1 then 0 else 1 end as video_unable
        from answer a
        inner join video c on c.id = a.video_id
        where (a.check = 1 or (a.check = 0 and a.delete_tag = 1 and a.ic_group is not null)) and a.wx_user = ?
          and c.wx_user != a.wx_user
         
        order by a.id desc
        limit ?,?
      `, [wx_user, skip, take])
      total = await this.repository.query(`
        select count(1) as total
        from answer a
        inner join video c on c.id = a.video_id
        where (a.check = 1 or (a.check = 0 and a.delete_tag = 1 and a.ic_group is not null)) and a.wx_user = ?
          and c.wx_user != a.wx_user
      `, [wx_user])
    }

    dataList.map(e => {
      if (e.profit_unit_price && Number(e.profit_unit_price) > 0) {
        e.profit_unit_price = (Number(e.profit_unit_price || 0) / 100).toFixed(2)
      } else {
        e.profit_unit_price = 0
      }
      if (e.check_time) {
        e.check_time = e.check_time.getTime()
      }
    })
    return { data: dataList, total: Number(total[0].total || 0) }
  }

  /**
   * 创建一个收益
   * @param data
   * @returns
   */
  async create(data: Profit): Promise<Profit> {
    return await this.repository.save(data);
  }

  /**
   * 查询用户所有未提现的收益
   * @param wx_user
   * @returns
   */
  async findAll_Entry(wx_user: string): Promise<Profit[]> {
    return await this.repository.find({ where: { author_wx_user: wx_user, status: profitEnum.entry } });
  }

  /**
   * 发起退款
   * @param wx_user 
   * @param answer_id 
   */
  async refund(wx_user: string, answer_id: number, video_id: number, errorType: EnumProfitRefundReasonType, platform: string, account: string, ic_name: string,
    avatar_id: string, avatar_img: string, img: string, img_id: string) {
    let db: DataBase = new DataBase()
    let connection = await db.getConnection()
    const queryRunner = connection.createQueryRunner()
    await queryRunner.connect()
    // 开始事务
    await queryRunner.startTransaction()
    try {
      if (answer_id) {
        await this.repository.createQueryBuilder(null, queryRunner)
          .update({ status: profitEnum.refoundIng, update_time: new Date(), refund_type: errorType })
          .where({ use_wx_user: wx_user, answer_id: answer_id })
          .execute()
      } else if (video_id) {
        await this.profitUnLockHomeRepository.createQueryBuilder(null, queryRunner)
          .update({ status: EnumProfitUnLockHome_Status.refoundIng, update_time: new Date(), refund_type: errorType })
          .where({ use_wx_user: wx_user, video_id: video_id })
          .execute()
      }
      //添加报错信息
      let answerReportError = new AnswerReportErrors()
      answerReportError.wx_user = wx_user
      answerReportError.answer_id = answer_id
      answerReportError.create_time = new Date()
      answerReportError.type = errorType
      answerReportError.platform = platform
      answerReportError.account = account
      answerReportError.ic_name = ic_name
      answerReportError.avatar_id = avatar_id
      answerReportError.avatar_img = avatar_img
      answerReportError.img = img
      answerReportError.img_id = img_id
      answerReportError.source = ReportSourceEnum.refund
      await this.answerReportErrorsRepository.createQueryBuilder(null, queryRunner)
        .insert()
        .into(AnswerReportErrors)
        .values(answerReportError)
        .execute()

      await queryRunner.commitTransaction()
      await queryRunner.release();

      //删除缓存-我的消费
      await this.redisCacheService.clear(`${wx_user}:consume_list:consume*`)
    } catch (err) {
      // 有错误做出回滚更改
      await queryRunner.rollbackTransaction()
      await queryRunner.release();
      return err
    }

  }

  /**
   * 同意退款
   * @param wx_user 
   * @param answer_id 
   * @returns 
   */
  async refundSuccess(id: number, type: string) {
    //查询收益详情
    let findProfit
    let findPayment
    if (type === 'profit') {
      findProfit = await this.repository.findOne({ where: { id: id } })
      if (findProfit?.payment_on_behalf) {
        findPayment = await this.repository.findOne({ where: { id: findProfit.payment_on_behalf } })
      }
    } else {
      findProfit = await this.profitUnLockHomeRepository.query(`
        select profit_unlock_home.*, video.wx_user as author_wx_user, answer.id as answer_id
        from profit_unlock_home
        inner join video on video.id = profit_unlock_home.video_id
        inner join answer on answer.video_id = video.id and answer.check = 1 and answer.delete_tag = 0
        where profit_unlock_home.id = ?
      `, [id])
      findProfit = findProfit[0]
    }
    if (!findProfit) {
      return '收益不存在'
    }
    //查询视频
    let findAnswer = findProfit //await this.answerRepository.findOne({where:{id: findProfit.answer_id}})
    let findQuestion: Questions[] = []
    let findReward: RewardSuccess[] = []
    //查询视频详情
    let findVideo: any
    if (findProfit.video_id) {
      findVideo = await this.profitRefundRepository.query(`
        select video.ic_group, wx_user.id as wx_user_id from video
        inner join wx_user on wx_user.openid = video.wx_user
        where video.id = ? 
      `, [findProfit.video_id])
    } else {
      findVideo = await this.profitRefundRepository.query(`
        select video.ic_group, wx_user.id as wx_user_id from video
        inner join wx_user on wx_user.openid = video.wx_user
        inner join answer on answer.video_id = video.id and answer.check = 1
        inner join profit on profit.answer_id = answer.id
        where profit.id = ?
      `, [id])
    }
    if (type === 'profit') {
      findAnswer = await this.answerRepository.findOne({ where: { id: findProfit.answer_id } })
      //查找同提问
      findQuestion = await this.questionsRepository.query(`
        select questions.* from questions
        inner join answer on answer.video_id = questions.video_id
        where questions.wx_user = ? and answer.id = ?
      `, [findProfit.use_wx_user, findProfit.answer_id])
      //查询是否有悬赏
      findReward = await this.rewardSuccessRepository.query(`
        select * from reward_success
        inner join answer on answer.video_id = reward_success.video_id
        where answer.id = ? and reward_success.wx_user = ?
      `, [findProfit.answer_id, findProfit.use_wx_user])
    }

    let db: DataBase = new DataBase()
    let connection = await db.getConnection()
    const queryRunner = connection.createQueryRunner()
    await queryRunner.connect()
    // 开始事务
    await queryRunner.startTransaction()
    try {
      //修改同提问答案收到的时间
      if (findQuestion.length > 0) {
        //清空同提问时间
        await this.questionsRepository.createQueryBuilder(null, queryRunner)
          .update({ answer_time: null, post_answer: 0 })
          .where({ id: findQuestion[0].id })
          .execute()

        console.log(findReward, 'finreww')
        //删除悬赏
        if (findReward.length > 0) {
          await this.rewardSuccessRepository.createQueryBuilder(null, queryRunner)
            .delete()
            .where({ video_id: findReward[0].video_id, wx_user: findProfit.use_wx_user })
            .execute()
          await this.rewardRepository.createQueryBuilder(null, queryRunner)
            .update({ pay_status: payStatusEnum.reject })
            .where({ video_id: findReward[0].video_id, wx_user: findProfit.use_wx_user, pay_order: findReward[0].pay_order })
            .execute()
        }
      }

      if (type === 'profit') {
        let ids = [id]
        if (findPayment) {
          ids.push(findPayment.id)
        }
        await this.repository.createQueryBuilder(null, queryRunner)
          .delete()
          .where({ id: In(ids) })
          .execute()
      } else {
        await this.profitUnLockHomeRepository.createQueryBuilder(null, queryRunner)
          .delete()
          .where({ id: id })
          .execute()
      }

      //添加收益退款记录
      let profitRefund = new ProfitRefund()
      profitRefund.answer_id = findProfit.answer_id
      profitRefund.author_wx_user = findProfit.author_wx_user
      profitRefund.use_wx_user = findProfit.use_wx_user
      profitRefund.status = profitRefundStatusEnum.refoundSuccess
      profitRefund.notes = findProfit.notes
      profitRefund.service_charge = findProfit.service_charge
      profitRefund.unit_price = findProfit.unit_price
      profitRefund.type = findProfit.type
      profitRefund.update_time = findProfit.update_time
      profitRefund.create_time = findProfit.create_time
      profitRefund.delivery_time = findProfit.create_time
      profitRefund.refund_type = type === 'profit' ? EnumProfitRefundType.profit : EnumProfitRefundType.unlock_home
      profitRefund.reason = findProfit.refund_type
      let addProfitRefund = await this.profitRefundRepository.createQueryBuilder(null, queryRunner)
        .insert()
        .into(ProfitRefund)
        .values(profitRefund)
        .execute()
      //通知申请人已退款
      let noticeList: Array<Notices> = []
      let notice = new Notices()
      notice.answer_id = findProfit.answer_id
      notice.check = NoticeCheckEnum.yes
      notice.create_time = new Date()
      notice.type = NoticeTypeEnum.refund_accept
      notice.video_id = findAnswer.video_id
      notice.wx_user = findProfit.use_wx_user
      if (addProfitRefund.identifiers.length > 0) {
        notice.profit_refund_id = addProfitRefund.identifiers[0].id
        if (findPayment) {
          let profitRefund2 = new ProfitRefund()
          profitRefund2.answer_id = findPayment.answer_id
          profitRefund2.author_wx_user = findPayment.author_wx_user
          profitRefund2.use_wx_user = findPayment.use_wx_user
          profitRefund2.payment_on_behalf = notice.profit_refund_id
          profitRefund2.status = profitRefundStatusEnum.refoundSuccess
          profitRefund2.notes = '他人代付'
          profitRefund2.service_charge = findProfit.service_charge
          profitRefund2.unit_price = findProfit.unit_price
          profitRefund2.type = findPayment.type
          profitRefund2.update_time = findPayment.update_time
          profitRefund2.create_time = findPayment.create_time
          profitRefund2.delivery_time = findPayment.create_time
          profitRefund2.refund_type = type === 'profit' ? EnumProfitRefundType.profit : EnumProfitRefundType.unlock_home
          profitRefund2.reason = findPayment.refund_type
          let refundResult = await this.profitRefundRepository.createQueryBuilder(null, queryRunner)
            .insert()
            .into(ProfitRefund)
            .values(profitRefund2)
            .execute()

          if (refundResult.identifiers.length > 0) {
            notice = new Notices()
            notice.answer_id = findPayment.answer_id
            notice.check = NoticeCheckEnum.yes
            notice.create_time = new Date()
            notice.type = NoticeTypeEnum.refund_accept
            notice.video_id = findAnswer.video_id
            notice.wx_user = findPayment.use_wx_user
            notice.profit_refund_id = refundResult.identifiers[0].id
            noticeList.push(notice)
          }
        } else {
          noticeList.push(notice)
        }
      }
      await this.noticesRepository.createQueryBuilder(null, queryRunner).insert().into(Notices).values(noticeList).execute()
      WXAPIOBJ.clearPayWallet(findProfit.use_wx_user)

      await queryRunner.commitTransaction()
      await queryRunner.release();


      //删除缓存-用户消费记录
      if (findVideo && findVideo.length > 0) {
        findVideo = findVideo[0]
        console.log(findProfit)
        console.log(findVideo)
        console.log(`${findProfit.use_wx_user}:icinfo:icgroup:${findVideo.ic_group}:videos`, '------')
        await this.redisCacheService.del(`${findProfit.use_wx_user}:icinfo:icgroup:${findVideo.ic_group}:videos`)
        await this.redisCacheService.del(`${findProfit.use_wx_user}:icinfo:wxuser:${findVideo.wx_user_id}:videos`)
        await this.redisCacheService.clear(`${findProfit.use_wx_user}:consume_list*`)
        await this.redisCacheService.clear(`${findProfit.use_wx_user}:consume_total:consume*`)

        await this.redisCacheService.clear(`${findProfit.author_wx_user}:profit_list*`)
        await this.redisCacheService.clear(`${findProfit.author_wx_user}:profit_total:income*`)

        if (findPayment) {
          await this.redisCacheService.del(`${findPayment.use_wx_user}:icinfo:icgroup:${findVideo.ic_group}:videos`)
          await this.redisCacheService.del(`${findPayment.use_wx_user}:icinfo:wxuser:${findVideo.wx_user_id}:videos`)
          await this.redisCacheService.clear(`${findPayment.use_wx_user}:consume_list*`)
          await this.redisCacheService.clear(`${findPayment.use_wx_user}:consume_total:consume*`)
        }
      }


      this.wsStartGateway.postUpdateNotice(notice.wx_user)
      this.wsStartGateway.postUpdateVideo(findAnswer.video_id)
      this.wsStartGateway.postUpdateMyData(findProfit.use_wx_user, findAnswer.video_id)
      if (findPayment) {
        this.wsStartGateway.postUpdateMyData(findPayment.use_wx_user, findAnswer.video_id)
      }
      // this.wsStartGateway.postUpdateProfitRefund(findProfit.use_wx_user, findAnswer.video_id)

    } catch (err) {
      // 有错误做出回滚更改
      await queryRunner.rollbackTransaction()
      await queryRunner.release();
      return err
    }
  }

  /**
   * 拒绝退款
   * @param wx_user 
   * @param answer_id 
   * @returns 
   */
  async refundReject(id: number, type: string, reject_reason: number) {
    //查询收益详情
    let findProfit
    let findPayment
    if (type === 'profit_unlock_home') {
      findProfit = await this.profitUnLockHomeRepository.findOne({ where: { id: id } })
    } else {
      findProfit = await this.repository.findOne({ where: { id: id } })
      if (findProfit?.payment_on_behalf) {
        findPayment = await this.repository.findOne({ where: { id: findProfit.payment_on_behalf } })
      }
    }
    if (!findProfit) {
      return '收益不存在'
    }
    let findAnswer = findProfit
    if (type === 'profit') {
      findAnswer = await this.answerRepository.findOne({ where: { id: findProfit.answer_id } })
    }
    let findReason: RejectReason = await this.rejectReasonRepository.findOne({ where: { id: reject_reason } })
    if (!findReason) {
      return '驳回原因不存在'
    }

    let db: DataBase = new DataBase()
    let connection = await db.getConnection()
    const queryRunner = connection.createQueryRunner()
    await queryRunner.connect()
    // 开始事务
    await queryRunner.startTransaction()
    try {
      if (type === 'profit') {
        await this.repository.createQueryBuilder(null, queryRunner).update({ status: profitEnum.entry, update_time: new Date(), reject_reason: findReason.reason }).where({ id: id }).execute()
        if (findPayment) {
          await this.repository.createQueryBuilder(null, queryRunner).update({ status: profitEnum.entry, update_time: new Date(), reject_reason: findReason.reason }).where({ id: findPayment.id }).execute()
        }
      } else {
        await this.profitUnLockHomeRepository.createQueryBuilder(null, queryRunner).update({ status: EnumProfitUnLockHome_Status.entry, update_time: new Date(), reject_reason: findReason.reason }).where({ id: id }).execute()

      }
      //通知申请人拒绝退款
      let noticeList: Array<Notices> = []
      let notice = new Notices()
      notice.answer_id = findProfit.answer_id
      notice.check = NoticeCheckEnum.yes
      notice.create_time = new Date()
      notice.type = NoticeTypeEnum.refund_reject
      notice.video_id = findAnswer.video_id
      notice.wx_user = findProfit.use_wx_user
      notice.reject_reason = findReason.reason
      notice.profit_time = findProfit.create_time

      if (findPayment) {
        let notice = new Notices()
        notice.answer_id = findPayment.answer_id
        notice.check = NoticeCheckEnum.yes
        notice.create_time = new Date()
        notice.type = NoticeTypeEnum.refund_reject
        notice.video_id = findAnswer.video_id
        notice.wx_user = findPayment.use_wx_user
        notice.reject_reason = findReason.reason
        notice.profit_time = findPayment.create_time
        noticeList.push(notice)
      } else {
        noticeList.push(notice)
      }
      await this.noticesRepository.createQueryBuilder(null, queryRunner).insert().into(Notices).values(noticeList).execute()

      await queryRunner.commitTransaction()
      await queryRunner.release();

      //删除缓存-我的消费记录
      await this.redisCacheService.clear(`${findProfit.use_wx_user}:consume_list:consume*`)

      noticeList.map(e => {
        this.wsStartGateway.postUpdateNotice(e.wx_user)
      })
      this.wsStartGateway.postUpdateVideo(findAnswer.video_id)
      this.wsStartGateway.postUpdateMyData(findProfit.use_wx_user, findAnswer.video_id)
      if (findPayment) {
        this.wsStartGateway.postUpdateMyData(findPayment.use_wx_user, findAnswer.video_id)
      }
    } catch (err) {
      // 有错误做出回滚更改
      await queryRunner.rollbackTransaction()
      await queryRunner.release();
      return err
    }

  }

  /**
   * 查询视频下所有退款申请
   * @param video_id 
   */
  async refundListByVideoId(skip: number, take: number, video_id: number) {
    let dataList = await this.repository.query(`
      select p.* from profit p
      inner join answer b on b.id = p.answer_id
      where (p.status = 3 or p.status = 4) and b.video_id = ?
      order by p.update_time desc
      limit ?,?
    `, [video_id, skip, take])

    let total = await this.repository.query(`
      select count(1) as total from profit p
      inner join answer b on b.id = p.answer_id
      where (p.status = 3 or p.status = 4) and b.video_id = ?
    `, [video_id])

    return { data: dataList, total: Number(total[0].total) }
  }

  async refundList(skip: number, take: number, video_id: number, selectType: number) {
    let params = [skip, take], selectTypeSql = '', sql = '', sqlTotal = ''
    let paramsTotal = []

    switch (selectType) {
      case 0:
        sql = `select * from (
          select p.id,p.use_wx_user,wx_user.name as user_name,p.unit_price,p.service_charge,p.update_time, p.status
            ,video.id as video_id,internet_celebrity.name as ic_name, internet_celebrity.img, 
            internet_celebrity.avatar_img,platform.platform,internet_celebrity.account, video.video_url as video_url,
            video.video_url_source, video.video_cover, video.type as video_type,'profit' as profit_type, p.refund_type
          from profit p
          inner join answer b on b.id = p.answer_id
          left join video on video.id = b.video_id
          left join internet_celebrity on internet_celebrity.ic_group = video.ic_group
          left join platform on platform.id = internet_celebrity.platform
          inner join wx_user on wx_user.openid = p.use_wx_user
          where (p.status = 3 or p.status = 4) and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
            and p.unit_price > 0
          union all
          select p.id,p.use_wx_user,wx_user.name as user_name,p.unit_price,p.service_charge,p.update_time, p.status
            ,video.id as video_id,internet_celebrity.name as ic_name, internet_celebrity.img, 
            internet_celebrity.avatar_img,platform.platform,internet_celebrity.account, video.video_url as video_url,
            video.video_url_source, video.video_cover, video.type as video_type,'profit_unlock_home' as profit_type, p.refund_type
          from profit_unlock_home p
          left join video on video.id = p.video_id
          left join internet_celebrity on internet_celebrity.ic_group = video.ic_group
          left join platform on platform.id = internet_celebrity.platform
          inner join wx_user on wx_user.openid = p.use_wx_user
          where (p.status = 3 or p.status = 4) and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
          ) p
          order by p.update_time asc limit ?,?
        `
        sqlTotal = `
          select sum(a.total) as total from(
            select count(1) as total from profit p
            inner join answer b on b.id = p.answer_id
            left join video on video.id = b.video_id
            where (p.status = 3 or p.status = 4) and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
              and p.unit_price > 0
            union all
            select count(1) as total from profit_unlock_home p
            left join video on video.id = p.video_id
            where (p.status = 3 or p.status = 4) and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
          ) a
        `
        if (video_id) {
          params.splice(0, 0, video_id)
          params.splice(0, 0, video_id)
          paramsTotal.push(video_id)
          paramsTotal.push(video_id)
        }
        break;
      case 1:
        sql = `select * from (
          select p.id,p.use_wx_user,wx_user.name as user_name,p.unit_price,p.service_charge,p.update_time, p.status
            ,video.id as video_id,internet_celebrity.name as ic_name, internet_celebrity.img, 
            internet_celebrity.avatar_img,platform.platform,internet_celebrity.account, video.video_url as video_url,
            video.video_url_source, video.video_cover, video.type as video_type,'profit' as profit_type, p.reason as refund_type
          from profit_refund p
          inner join answer b on b.id = p.answer_id
          left join video on video.id = b.video_id
          left join internet_celebrity on internet_celebrity.ic_group = video.ic_group
          left join platform on platform.id = internet_celebrity.platform
          inner join wx_user on wx_user.openid = p.use_wx_user
          where (p.status = 4) and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
          ) p
          order by p.update_time asc limit ?,?
        `
        sqlTotal = `
          select sum(a.total) as total from(
            select count(1) as total from profit_refund p
            inner join answer b on b.id = p.answer_id
            left join video on video.id = b.video_id
            where (p.status = 4) and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
          ) a
        `
        if (video_id) {
          params.splice(0, 0, video_id)
          paramsTotal.push(video_id)
        }
        break;
      case 2:
        sql = `select * from (
            select p.id,p.use_wx_user,wx_user.name as user_name,p.unit_price,p.service_charge,p.update_time, p.status
              ,video.id as video_id,internet_celebrity.name as ic_name, internet_celebrity.img, 
              internet_celebrity.avatar_img,platform.platform,internet_celebrity.account, video.video_url as video_url,
              video.video_url_source, video.video_cover, video.type as video_type,'profit' as profit_type, p.refund_type
            from profit p
            inner join answer b on b.id = p.answer_id
            left join video on video.id = b.video_id
            left join internet_celebrity on internet_celebrity.ic_group = video.ic_group
            left join platform on platform.id = internet_celebrity.platform
            inner join wx_user on wx_user.openid = p.use_wx_user
            where p.refund_type is not null and p.status = 1 and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
              and p.unit_price > 0
            union all
            select p.id,p.use_wx_user,wx_user.name as user_name,p.unit_price,p.service_charge,p.update_time, p.status
              ,video.id as video_id,internet_celebrity.name as ic_name, internet_celebrity.img, 
              internet_celebrity.avatar_img,platform.platform,internet_celebrity.account, video.video_url as video_url,
              video.video_url_source, video.video_cover, video.type as video_type,'profit_unlock_home' as profit_type, p.refund_type
            from profit_unlock_home p
            left join video on video.id = p.video_id
            left join internet_celebrity on internet_celebrity.ic_group = video.ic_group
            left join platform on platform.id = internet_celebrity.platform
            inner join wx_user on wx_user.openid = p.use_wx_user
            where p.refund_type is not null and p.status = 1 and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
            ) p
            order by p.update_time asc limit ?,?
          `
        sqlTotal = `
            select sum(a.total) as total from(
              select count(1) as total from profit p
              inner join answer b on b.id = p.answer_id
              left join video on video.id = b.video_id
              where p.refund_type is not null and p.status = 1 and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
                and p.unit_price > 0
              union all
              select count(1) as total from profit_unlock_home p
              left join video on video.id = p.video_id
              where p.refund_type is not null and p.status = 1 and p.type != 0 ${video_id ? 'and video.id = ?' : ''}
            ) a
          `
        if (video_id) {
          params.splice(0, 0, video_id)
          params.splice(0, 0, video_id)
          paramsTotal.push(video_id)
          paramsTotal.push(video_id)
        }
        break;
    }

    let dataList = await this.repository.query(sql, params)

    dataList.map(e => {
      switch (e.refund_type) {
        case EnumProfitRefundReasonType.answer_error:
          e.refund_reason = EnumProfitRefundReasonText.answer_error
          break
        case EnumProfitRefundReasonType.context_cover_not_comp:
          e.refund_reason = EnumProfitRefundReasonText.context_cover_not_comp
          break
        case EnumProfitRefundReasonType.answer_not_new:
          e.refund_reason = EnumProfitRefundReasonText.answer_not_new
          break
        case EnumProfitRefundReasonType.context_cover_not_mis:
          e.refund_reason = EnumProfitRefundReasonText.context_cover_not_mis
          break
        case EnumProfitRefundReasonType.ic_cover_not_cmpm:
          e.refund_reason = EnumProfitRefundReasonText.ic_cover_not_cmpm
          break
        case EnumProfitRefundReasonType.ic_cover_not_mis:
          e.refund_reason = EnumProfitRefundReasonText.ic_cover_not_mis
          break
        case EnumProfitRefundReasonType.other_ic_error:
          e.refund_reason = EnumProfitRefundReasonText.other_ic_error
          break
      }
    })

    let total = await this.repository.query(sqlTotal, paramsTotal)

    return { data: dataList, total: Number(total[0].total) }
  }

  async insertProfitRecord(video_id: number, wx_user: string) {
    //查询答案作者是否是自己，如果是不用添加空收益
    let findAnswerIsMe = await this.answerRepository.findOne({ where: { video_id: video_id, wx_user: wx_user, check: 1 } })
    if (findAnswerIsMe) {
      return true
    } else {
      let findProfit = await this.repository.query(`
        select profit.id from profit
        inner join answer on answer.id = profit.answer_id
        where answer.video_id = ? and profit.use_wx_user = ?
      `, [video_id, wx_user])
      if (findProfit.length === 0) {
        let findAnswer = await this.answerRepository.findOne({ where: { video_id: video_id, check: 1 } })
        if (findAnswer) {
          let addProfit: Profit = new Profit()
          addProfit.answer_id = findAnswer.id
          addProfit.author_wx_user = findAnswer.wx_user
          addProfit.use_wx_user = wx_user
          addProfit.status = profitEnum.entry
          addProfit.create_time = new Date()
          addProfit.update_time = new Date()
          addProfit.unit_price = 0
          addProfit.service_charge = 0
          addProfit.type = profitTypeEnum.consume
          return await this.repository.save(addProfit)
        }
      }
    }
  }

  async findIsRefund(wx_user: string, answer_id?: number, video_id?: number) {
    let result
    if (answer_id) {
      result = await this.repository.findOne({ where: { answer_id: answer_id, use_wx_user: wx_user } })
    } else {
      result = await this.profitUnLockHomeRepository.findOne({ where: { video_id: video_id, use_wx_user: wx_user } })
    }
    if (!result) {
      return false
    } else if (utils.validIsNull(result.refund_type)) {
      return false
    } else {
      return true
    }
  }

  async findConsumption(skip: number, take: number, wx_user: string) {
    let data = await this.repository.query(`
      select a.video_id,
        a.create_time,
        a.status,
        a.profit_type,
        a.unit_price,
        a.service_charge, 
        a.update_time, 
        a.consumption_type, 
        a.notes, 
        a.video_unable,
        a.load_type
      from (
        select c.id as video_id,a.create_time,a.status,c.profit_type,a.unit_price,a.service_charge, a.update_time, 'profit' as consumption_type,
              a.notes, case when (
                  select count(1) from questions
                  where questions.video_id = c.id and questions.wx_user = ?
                ) > 0 then 'question' else 'collection' end as load_type,
              (
                (
                  select count(1) from questions
                  inner join video on video.id = questions.video_id
                  where questions.video_id = c.id and questions.wx_user = ?
                      and questions.delete_tag = 0 and video.delete_tag = 0
                ) +
                (
                  select count(1) from wx_like_video
                  inner join video on video.id = wx_like_video.video_id
                  where wx_like_video.video_id = c.id and wx_like_video.wx_user = ?
                      and wx_like_video.delete_tag = 0 and video.delete_tag = 0
                )
              ) as video_unable
          from profit a
              inner join answer b on b.id = a.answer_id
              inner join video c on c.id = b.video_id
        where a.use_wx_user = ? and a.type = 1 and (a.status = 1 or a.status = 3)
        union all
        select '' as video_id, profit_refund.create_time, profit_refund.status, '' as profit_type, profit_refund.unit_price,
              profit_refund.service_charge,profit_refund.update_time, 'profit' as consumption_type, profit_refund.notes as notes, '' as load_type,
              '' as video_unable
          from profit_refund
        where profit_refund.use_wx_user = ? and profit_refund.type = 1 and profit_refund.status = 4
        union all
        select v.id as video_id,reward.pay_time as create_time,reward.pay_status as status
              ,v.profit_type,reward.unit_price - reward.service_charge as unit_price,reward.service_charge
            , reward.pay_time as update_time, case when reward.pay_status = 1 then 'profit' else 'reward' end as consumption_type,
              null as notes, 'question' as load_type,((
                  select count(1) from questions
                  left join video on video.id = questions.video_id
                  where questions.video_id = v.id and questions.wx_user = ?
                      and questions.delete_tag = 0 and video.delete_tag = 0
            )+(
              select count(1) from video
              where video.id = reward.video_id and video.wx_user = ? and video.delete_tag = 0
                  and video.original = 0
            )) as video_unable
        from reward
            left join video v on v.id = reward.video_id
        where reward.wx_user = ? and (reward.pay_status = 3 or reward.pay_status = 1)
          and reward.video_id not in (
            select answer.video_id from profit
              inner join answer on answer.id = profit.answer_id
            where profit.use_wx_user = ? and profit.type = 1 and (profit.status = 1 or profit.status = 3)
          )
        union all
        select video.id, profit_unlock_home.create_time, profit_unlock_home.status,
              profit_unlock_home.type, profit_unlock_home.unit_price, profit_unlock_home.service_charge,
              profit_unlock_home.update_time,'profit' as consumption_type, null as notes, 'collection' as load_type,(
                select count(1) from wx_like_video
                inner join video c on c.id = wx_like_video.video_id
                where wx_like_video.video_id = video.id and wx_like_video.wx_user = ?
                    and wx_like_video.delete_tag = 0 and c.delete_tag = 0
              ) as video_unable
        from profit_unlock_home
        inner join video on video.id = profit_unlock_home.video_id
        where profit_unlock_home.use_wx_user = ? and profit_unlock_home.type = 1 and (profit_unlock_home.status = 1 or profit_unlock_home.status = 3)
      ) a
      where a.unit_price > 0
      order by a.update_time desc
      limit ?,?
    `, [wx_user, wx_user, wx_user, wx_user, wx_user, wx_user, wx_user, wx_user, wx_user, wx_user, wx_user, skip, take])

    let total = await this.repository.query(`
      select count(1) as total from (
        select c.id as video_id, a.unit_price
        from profit a
        inner join answer b on b.id = a.answer_id
        inner join video c on c.id = b.video_id
        where a.use_wx_user = ? and a.type = 1 and (a.status = 1 or a.status = 3)
        union all
        select '' as video_id, profit_refund.unit_price
        from profit_refund
        where profit_refund.use_wx_user = ? and profit_refund.type = 1 and profit_refund.status = 4
        union all
        select v.id as video_id,reward.unit_price - reward.service_charge as unit_price
        from reward
        left join video v on v.id = reward.video_id
        where reward.wx_user = ? and (reward.pay_status = 3 or reward.pay_status = 1)
          and reward.video_id not in (
            select answer.video_id from profit
              inner join answer on answer.id = profit.answer_id
            where profit.use_wx_user = ? and profit.type = 1 and (profit.status = 1 or profit.status = 3)
          )
        union all
        select video.id as video_id, profit_unlock_home.unit_price
        from profit_unlock_home
        inner join video on video.id = profit_unlock_home.video_id
        where profit_unlock_home.use_wx_user = ? and profit_unlock_home.type = 1 and (profit_unlock_home.status = 1 or profit_unlock_home.status = 3)
      ) a
      where a.unit_price > 0
    `, [wx_user, wx_user, wx_user, wx_user, wx_user])

    data.map(e => {
      if (e.video_id) {
        e.video_id = Number(e.video_id)
      }
      if (e.update_time) {
        e.update_time = e.update_time.getTime()
        delete e.create_time
      }
      if (e.create_time) {
        e.create_time = e.create_time.getTime()
      }
      e.profit_type = Number(e.profit_type || 0)
      let unitPrice = e.unit_price
      if (!utils.validIsNull(unitPrice)) {
        let serviceCharge = e.service_charge
        if (utils.validIsNull(serviceCharge)) {
          serviceCharge = 0
        }
        serviceCharge = Number(serviceCharge)
        e.unit_price = (Number(unitPrice) + serviceCharge) / 100
        delete e.service_charge
      }
      if (utils.validIsNull(e.notes)) {
        delete e.notes
      }
      let video_unable = e.video_unable.toString()
      if (!utils.validIsNull(video_unable)) {
        e.video_unable = Number(video_unable)
      }

      if (e.consumption_type === 'profit') {
        e.consumption_type = 1
      } else {
        delete e.consumption_type
      }

      if (!utils.validIsNull(e.load_type)) {
        e.load_type = utils.loadTypeToNumber(e.load_type)
      } else {
        delete e.load_type
      }
    })

    return { data: data, total: Number(total[0].total || 0) }
  }

  async findTotalConsumptionByWxUserStatisticsDay(skip: number, take: number, wx_user: string) {
    let data = await this.answerRepository.query(`
      select substring(a.update_time, 1, 10) update_time,sum(a.unit_price)+sum(service_charge) totalPrice from (
        select profit.update_time, profit.unit_price, profit.service_charge from profit
        where profit.type = 1 and profit.use_wx_user = ? and (profit.status = 1 or profit.status = 3 or profit.status = 4)
        UNION
        select reward.pay_time as update_time, reward.unit_price - reward.service_charge as unit_price, reward.service_charge  from reward
        where reward.wx_user = ? and reward.pay_status = 1
      ) a
      group by substring(a.update_time, 1, 10)
      order by substring(a.update_time, 1, 10) desc
      limit ?,?
    `, [wx_user, wx_user, skip, take])

    let total = await this.answerRepository.query(`
      select count(1) as total from (
        select substring(a.update_time, 1, 10) update_time from (
          select profit.update_time, profit.unit_price, profit.service_charge from profit
          where profit.type = 1 and profit.use_wx_user = ? and (profit.status = 1 or profit.status = 3 or profit.status = 4)
          UNION
          select reward.pay_time as update_time, reward.unit_price - reward.service_charge as unit_price, reward.service_charge  from reward
          where reward.wx_user = ? and reward.pay_status = 1
        ) a
        group by substring(a.update_time, 1, 10)
      ) a
    `, [wx_user, wx_user])

    let profitPrice = await this.repository.query(`
      select sum(unit_price) as unit_price
      from (
        select case when a.unit_price is null then 0 else a.unit_price end as unit_price
        from (
          select sum(unit_price) + sum(service_charge) as unit_price
          from profit
          where use_wx_user = ?
            and type = 1
            and unit_price > 0
            and (status = 1 or status = 3)
        ) a
        union all
        select case when a.unit_price is null then 0 else a.unit_price end as unit_price
        from (
          select sum(unit_price) + sum(service_charge) as unit_price
          from profit_unlock_home
          where use_wx_user = ?
            and type = 1
            and unit_price > 0
            and (status = 1 or status = 3)
        ) a
      )a
    `, [wx_user, wx_user])

    let rewardPrice = await this.repository.query(`
      select a.amount
      from (
        select sum(unit_price) as amount
        from reward_success
        where wx_user = ?
          and video_id not in (
          select answer.video_id from profit
          inner join answer on answer.id = profit.answer_id
          where profit.use_wx_user = ?
        )
      ) a  
    `, [wx_user, wx_user])
    let totalPrice = Number(profitPrice[0].unit_price || 0) + Number(rewardPrice[0].amount || 0)
    return { data, total: Number(total[0].total || 0), totalPrice }
  }
}